package com.jzo2o.market.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.market.dto.request.CouponUseBackReqDTO;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.market.enums.CouponStatusEnum;
import com.jzo2o.market.mapper.CouponUseBackMapper;
import com.jzo2o.market.model.domain.Coupon;
import com.jzo2o.market.model.domain.CouponUseBack;
import com.jzo2o.market.service.ICouponService;
import com.jzo2o.market.service.ICouponUseBackService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;

/**
 * <p>
 * 优惠券使用回退记录 服务实现类
 * </p>
 * @author itcast
 * @since 2023-09-18
 */
@Service
public class CouponUseBackServiceImpl extends ServiceImpl<CouponUseBackMapper, CouponUseBack> implements ICouponUseBackService {
    @Resource
    private ICouponService couponService;

    @Override
    @Transactional
    public void useBack(CouponUseBackReqDTO couponUseBackReqDTO) {
        Long couponId = couponUseBackReqDTO.getId();
        Long userId = couponUseBackReqDTO.getUserId();
        Long ordersId = couponUseBackReqDTO.getOrdersId();

        Coupon coupon = couponService.getById(couponId);
        if (ObjectUtils.isEmpty(coupon) || ObjectUtils.notEqual(coupon.getUserId(), userId)) {
            throw new BadRequestException("优惠卷不存在");
        } else if (coupon.getStatus() != CouponStatusEnum.USED) {
            throw new BadRequestException("优惠卷未使用");
        } else if (ObjectUtils.notEqual(coupon.getOrdersId(), ordersId)) {
            throw new BadRequestException("优惠券对应订单错误");
        }

        LocalDateTime nowTime = LocalDateTime.now();
        CouponStatusEnum status = coupon.getValidityTime().isAfter(nowTime) ? CouponStatusEnum.NO_USE : CouponStatusEnum.INVALID;

        if (!couponService.lambdaUpdate()
                .eq(Coupon::getId, couponId)
                .set(Coupon::getUseTime, null)
                .set(Coupon::getStatus, status)
                .set(Coupon::getOrdersId, null)
                .update()) {
            throw new DBException("更新优惠卷表失败");
        }

        if (!this.save(CouponUseBack.builder()
                .couponId(couponId)
                .userId(userId)
                .useBackTime(nowTime)
                .writeOffTime(coupon.getUseTime())
                .build())) {
            throw new DBException("更新退回表失败");
        }
    }
}